/**  
 * <p>Title: OperaterFactory.java</p>  
 * <p>Description: 算子工厂</p>  
 * <p>Copyright: Copyright (c) 2018</p>    
 * @author ji'anyuan  
 * @date 2018年3月10日  
 * @version 1.0  
 */
package org.mango.jiayin.operater.operater;

import java.util.HashMap;
import java.util.Map;

import org.mango.jiayin.operater.utils.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>
 * Title: OperaterFactory
 * </p>
 * <p>
 * Description: 算子工厂
 * </p>
 * 
 * @author ji'anyuan
 * @date 2018年3月10日
 */
public class OperaterFactory {
	private static final Logger logger = LoggerFactory
			.getLogger(OperaterFactory.class);

	/**
	 * 算子的Map集合
	 */
	private static Map<String, Operater> opMap = new HashMap<String, Operater>();

	private static OperaterFactory instance;

	private OperaterFactory() {
		for (Class<?> opcls : ClassUtils.scanClassesWithInterface(
				Operater.class, "org.mango.jiayin.operater.operater.impl")) {
			addOperater(opcls);
		}
	}

	/**
	 * <p>
	 * Title: addOperater
	 * </p>
	 * <p>
	 * Description: 添加算子到集合中
	 * </p>
	 * 
	 * @param opcls
	 */
	private void addOperater(Class<?> opcls) {
		Operater op = getInstance(opcls);
		if (op != null) {
			String name = op.getName();

			opMap.put(name, op);
		}
	}

	/**
	 * <p>
	 * Title: getInstance
	 * </p>
	 * <p>
	 * Description: 实例化算子
	 * </p>
	 * 
	 * @param opcls
	 * @return
	 */
	private Operater getInstance(Class<?> opcls) {
		if (opcls == null) {
			return null;
		}

		Operater op = null;
		try {
			op = (Operater) opcls.newInstance();
		} catch (InstantiationException e) {
			logger.error("failed to instance class:{}",
					new Object[] { opcls, e });
		} catch (IllegalAccessException e) {
			logger.error("failed to instance class:{}",
					new Object[] { opcls, e });
		}
		return op;
	}

	/**
	 * 
	 * <p>
	 * Title: getInstance
	 * </p>
	 * <p>
	 * Description: 单例模式 懒汉式加载(安全)
	 * </p>
	 * 
	 * @return
	 */
	public static synchronized OperaterFactory getInstance() {
		if (instance == null) {
			instance = new OperaterFactory();
		}
		return instance;
	}

	/**
	 * 
	 * <p>
	 * Title: getOperater
	 * </p>
	 * <p>
	 * Description: 根据名字获取算子
	 * </p>
	 * 
	 * @param name
	 * @return
	 */
	public static Operater getOperater(String name) {
		if (opMap.containsKey(name)) {
			return opMap.get(name);
		}
		return null;
	}
}
